<template>
  <div class="app-container">
    <template v-if="isLoggedIn">
      <!-- 左侧侧边栏 -->
      <Sidebar @nav-click="handleNavClick" :user-info="userInfo" />

      <!-- 中间内容区 -->
      <div class="main-content">
        <!-- 会话列表 -->
        <ChatSidebar ref="chatSidebarRef" :external-contacts="addedContacts" @contact-selected="onContactSelected"
          v-if="currentView === 'chats' || currentView === 'chat'" />

        <!-- 好友列表 -->
        <FriendList :userId="userInfo.id" @select-friend="onFriendSelected" @load-messages="onLoadMessages"
          v-if="currentView === 'contacts'" />

        <!-- 聊天窗口 -->
        <ChatWindow ref="chatWindowRef" :contact="selectedContact" @message-sent="syncNewMessageToChatSidebar"
          v-if="currentView === 'chat'" />
      </div>
    </template>
    <AuthView v-else @login-success="handleLoginSuccess" />
  </div>
</template>

<script setup>
import { ref, shallowRef, onMounted, onUnmounted, watch } from 'vue';
import { parseToken } from './utils/jwt';
import Sidebar from './components/Sidebar.vue';
import ChatSidebar from './components/ChatSidebar.vue';
import FriendList from './components/FriendList.vue';
import ChatWindow from './components/ChatWindow.vue';
import AuthView from './views/AuthView.vue';
import request from './utils/request';

const isLoggedIn = ref(!!localStorage.getItem('token'));
const userInfo = ref({ userName: '', avatarUrl: '', id: '' });
const currentView = ref('chats');
const selectedContact = ref(null);
const addedContacts = ref([]);
const chatSidebarRef = shallowRef(null);
const chatWindowRef = shallowRef(null);

// WebSocket 相关
const ws = ref(null);
const wsConnected = ref(false);
let reconnectTimer = null;
const pendingMessages = ref([]);

onMounted(() => {
  if (isLoggedIn.value) {
    initUserInfo();
    initWebSocket();
  }
});

onUnmounted(() => {
  disconnectWebSocket();
});

watch(currentView, (newView) => {
  if (newView === 'chats') {
    processPendingMessages();
  }
});

const processPendingMessages = () => {
  if (!chatSidebarRef.value || pendingMessages.value.length === 0) return;

  pendingMessages.value.forEach(msg => {
    chatSidebarRef.value.updateWithNewMessage(msg.dialogueId, msg.message);
  });

  pendingMessages.value = [];
};

const initUserInfo = () => {
  try {
    const token = localStorage.getItem('token');
    const parsed = parseToken(token);
    userInfo.value = {
      userName: parsed.userName || '用户',
      avatarUrl: parsed.avatarUrl || '/images/avatar-default.png',
      id: parsed.id || ''
    };
  } catch (error) {
    console.error('解析用户信息失败', error);
    logout();
  }
};

// 初始化WebSocket连接，优化协议适配
const initWebSocket = () => {
  try {
    const token = localStorage.getItem('token');
    if (!token) throw new Error('No token for WebSocket');

    disconnectWebSocket();

    
    const wsUrl = `ws://127.0.0.1:8083/message?token=${token}`;

    ws.value = new WebSocket(wsUrl);

    ws.value.onopen = () => {
      console.log('WebSocket连接成功');
      wsConnected.value = true;
      clearReconnectTimer();
      // 连接成功后，可尝试发送心跳包等保持连接（如果后端需要）
      // sendHeartbeat(); 
    };

    ws.value.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        if (data.type === 'message') {
          console.log('');
          processIncomingMessage(data);
        } else if (data.type === 'error') {
          console.error('WebSocket错误:', data.message);
        }
        // 可扩展其他消息类型处理，比如心跳响应、系统通知等
      } catch (error) {
        console.error('处理WebSocket消息失败:', error);
      }
    };

    ws.value.onclose = (event) => {
      console.log('WebSocket连接关闭:', event.code, event.reason);
      wsConnected.value = false;
      scheduleReconnect();
    };

    ws.value.onerror = (error) => {
      console.error('WebSocket错误:', error);
      wsConnected.value = false;
      scheduleReconnect();
    };
  } catch (error) {
    console.error('初始化WebSocket失败:', error);
    scheduleReconnect();
  }
};

const disconnectWebSocket = () => {
  clearReconnectTimer();
  if (ws.value) {
    ws.value.onopen = null;
    ws.value.onmessage = null;
    ws.value.onclose = null;
    ws.value.onerror = null;
    ws.value.close();
    ws.value = null;
  }
};

const scheduleReconnect = () => {
  clearReconnectTimer();
  reconnectTimer = setTimeout(() => {
    if (!wsConnected.value) {
      initWebSocket();
    }
  }, 3000);
};

const clearReconnectTimer = () => {
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
};

// 处理收到的WebSocket消息，更新会话和聊天窗口
const processIncomingMessage = (data) => {
  const { dialogueId, content, fromId, fromName } = data;
  const isSelf = fromId === userInfo.value.id;

  const newMsg = {
    sender: isSelf ? '我' : fromName || '对方用户',
    content: content,
    time: new Date().toLocaleString('zh-CN', {
      hour: '2-digit',
      minute: '2-digit',
      hour12: false
    }),
    isSelf: isSelf
  };

  // 更新会话列表
  if (chatSidebarRef.value && (currentView.value === 'chats' || currentView.value === 'chat')) {
    chatSidebarRef.value.updateWithNewMessage(dialogueId, newMsg);
  } else {
    pendingMessages.value.push({
      dialogueId: dialogueId,
      message: newMsg
    });
  }

  // 如果当前在聊天窗口且是当前选中的会话，更新聊天窗口内容
if (currentView.value === 'chat' && selectedContact.value && selectedContact.value.dialogueId === dialogueId) {
  const formattedMessage = {
    id: Date.now(),
    content: newMsg.content,
    time: new Date().toISOString(), 
    isSelf: newMsg.isSelf, // 区分自己和对方的消息
    avatar: newMsg.isSelf 
      ? localStorage.getItem('avatarUrl') || '/images/avatar-self.png' // 自己的头像
      : selectedContact.value.avatar || '/images/avatar-other.png', // 对方的头像
    sender: newMsg.isSelf 
      ? localStorage.getItem('userName') || '我' // 自己的名称
      : selectedContact.value.name || '对方' // 对方的名称
  };
  
  // 确保messages数组存在
  if (!selectedContact.value.messages) {
    selectedContact.value.messages = [];
  }
  
  // 使用Vue响应式方法添加消息
  selectedContact.value.messages.push(formattedMessage);
  
  // 触发DOM更新后滚动到底部
  nextTick(() => {
    scrollToBottom();
  });
}
}
const handleNavClick = (type) => {
  if (type === 'chats') {
    currentView.value = 'chats';
  } else if (type === 'contacts') {
    currentView.value = 'contacts';
  }
};

const onContactSelected = (contact) => {
  selectedContact.value = contact;
  currentView.value = 'chat';
  if (chatWindowRef.value) {
    chatWindowRef.value.loadMessages(contact.dialogueId);
  }
};

const onFriendSelected = (contact) => {
  if (!addedContacts.value.some(c => c.id === contact.id)) {
    addedContacts.value.push(contact);
  }
  selectedContact.value = contact;
  currentView.value = 'chat';
};

const onLoadMessages = (dialogueId) => {
  if (chatWindowRef.value) {
    chatWindowRef.value.loadMessages(dialogueId);
  }
};

const syncNewMessageToChatSidebar = ({ contactId, message }) => {
  if (chatSidebarRef.value && (currentView.value === 'chats' || currentView.value === 'chat')) {
    chatSidebarRef.value.updateWithNewMessage(contactId, {
      ...message,
      sender: '我',
      isSelf: true
    });
  } else {
    console.log('ChatSidebar 组件不可用，消息同步被忽略');
  }

  sendMessage(contactId, message.content);
};

// 发送消息到WebSocket，与后端交互
const sendMessage = (dialogueId, content) => {
  if (!wsConnected.value || !ws.value) {
    console.error('WebSocket未连接，无法发送消息');
    // 可考虑将消息暂存，待连接恢复后发送（如果业务需要）
    return;
  }

  try {
    const messageData = {
      type: 'message',
      dialogueId: dialogueId,
      content: content,
      fromId: userInfo.value.id,
      fromName: userInfo.value.userName
    };

    ws.value.send(JSON.stringify(messageData));
  } catch (error) {
    console.error('发送消息失败:', error);
  }
};

const handleLoginSuccess = () => {
  isLoggedIn.value = true;
  initUserInfo();
  initWebSocket();
  currentView.value = 'chats';
};

const logout = () => {
  localStorage.removeItem('token');
  isLoggedIn.value = false;
  disconnectWebSocket();
  userInfo.value = { userName: '', avatarUrl: '', id: '' };
  selectedContact.value = null;
};
</script>

<style scoped>
.app-container {
  display: flex;
  height: 100vh;
  background: url('/images/bk.jpg') no-repeat center center fixed;
  background-size: cover;
}

.main-content {
  display: flex;
  flex: 1;
  overflow: hidden;
}
</style>